// RAP [rh] Keys completely disabled as not implemented in RWT
///*******************************************************************************
// * Copyright (c) 2000, 2009 IBM Corporation and others.
// * All rights reserved. This program and the accompanying materials
// * are made available under the terms of the Eclipse Public License v1.0
// * which accompanies this distribution, and is available at
// * http://www.eclipse.org/legal/epl-v10.html
// *
// * Contributors:
// *     IBM Corporation - initial API and implementation
// *******************************************************************************/
//
//package org.eclipse.ui.internal.keys;
//
//import java.io.BufferedWriter;
//import java.io.FileWriter;
//import java.io.IOException;
//import java.io.Writer;
//import java.util.ArrayList;
//import java.util.Arrays;
//import java.util.Collection;
//import java.util.Collections;
//import java.util.Comparator;
//import java.util.HashMap;
//import java.util.HashSet;
//import java.util.Iterator;
//import java.util.List;
//import java.util.Map;
//import java.util.ResourceBundle;
//import java.util.Set;
//
//import org.eclipse.core.commands.Category;
//import org.eclipse.core.commands.Command;
//import org.eclipse.core.commands.CommandManager;
//import org.eclipse.core.commands.ParameterizedCommand;
//import org.eclipse.core.commands.common.NotDefinedException;
//import org.eclipse.core.commands.contexts.Context;
//import org.eclipse.core.commands.contexts.ContextManager;
//import org.eclipse.core.runtime.IStatus;
//import org.eclipse.core.runtime.SafeRunner;
//import org.eclipse.core.runtime.Status;
//import org.eclipse.jface.bindings.Binding;
//import org.eclipse.jface.bindings.BindingManager;
//import org.eclipse.jface.bindings.Scheme;
//import org.eclipse.jface.bindings.TriggerSequence;
//import org.eclipse.jface.bindings.keys.KeyBinding;
//import org.eclipse.jface.bindings.keys.KeySequence;
//import org.eclipse.jface.bindings.keys.KeySequenceText;
//import org.eclipse.jface.bindings.keys.KeyStroke;
//import org.eclipse.jface.contexts.IContextIds;
//import org.eclipse.jface.dialogs.IDialogConstants;
//import org.eclipse.jface.dialogs.MessageDialog;
//import org.eclipse.jface.preference.IPreferenceStore;
//import org.eclipse.jface.preference.PreferencePage;
//import org.eclipse.jface.util.SafeRunnable;
//import org.eclipse.swt.SWT;
//import org.eclipse.swt.events.DisposeEvent;
//import org.eclipse.swt.events.DisposeListener;
//import org.eclipse.swt.events.FocusEvent;
//import org.eclipse.swt.events.FocusListener;
//import org.eclipse.swt.events.ModifyEvent;
//import org.eclipse.swt.events.ModifyListener;
//import org.eclipse.swt.events.MouseAdapter;
//import org.eclipse.swt.events.MouseEvent;
//import org.eclipse.swt.events.SelectionAdapter;
//import org.eclipse.swt.events.SelectionEvent;
//import org.eclipse.swt.events.SelectionListener;
//import org.eclipse.swt.graphics.Image;
//import org.eclipse.swt.graphics.Point;
//import org.eclipse.swt.layout.GridData;
//import org.eclipse.swt.layout.GridLayout;
//import org.eclipse.swt.widgets.Button;
//import org.eclipse.swt.widgets.Combo;
//import org.eclipse.swt.widgets.Composite;
//import org.eclipse.swt.widgets.Control;
//import org.eclipse.swt.widgets.FileDialog;
//import org.eclipse.swt.widgets.Group;
//import org.eclipse.swt.widgets.Label;
//import org.eclipse.swt.widgets.Menu;
//import org.eclipse.swt.widgets.MenuItem;
//import org.eclipse.swt.widgets.TabFolder;
//import org.eclipse.swt.widgets.TabItem;
//import org.eclipse.swt.widgets.Table;
//import org.eclipse.swt.widgets.TableColumn;
//import org.eclipse.swt.widgets.TableItem;
//import org.eclipse.swt.widgets.Text;
//import org.eclipse.ui.IWorkbench;
//import org.eclipse.ui.IWorkbenchPreferencePage;
//import org.eclipse.ui.PlatformUI;
//import org.eclipse.ui.activities.IActivityManager;
//import org.eclipse.ui.commands.ICommandService;
//import org.eclipse.ui.contexts.IContextService;
//import org.eclipse.ui.internal.IPreferenceConstants;
//import org.eclipse.ui.internal.IWorkbenchHelpContextIds;
//import org.eclipse.ui.internal.WorkbenchPlugin;
//import org.eclipse.ui.internal.misc.StatusUtil;
//import org.eclipse.ui.internal.util.PrefUtil;
//import org.eclipse.ui.internal.util.Util;
//import org.eclipse.ui.keys.IBindingService;
//import org.eclipse.ui.statushandlers.StatusManager;
//
//import com.ibm.icu.text.Collator;
//import com.ibm.icu.text.MessageFormat;
//
///**
// * The preference page for defining keyboard shortcuts. While some of its
// * underpinning have been made generic to "bindings" rather than "key bindings",
// * it will still take some work to remove the link entirely.
// * 
// * @since 3.0
// */
//public final class KeysPreferencePage extends PreferencePage implements
//		IWorkbenchPreferencePage {
//
//	/**
//	 * A selection listener to be used on the columns in the table on the view
//	 * tab. This selection listener modifies the sort order so that the
//	 * appropriate column is in the first position.
//	 * 
//	 * @since 3.1
//	 */
//	private class SortOrderSelectionListener extends SelectionAdapter {
//
//		/**
//		 * The column to be put in the first position. This value should be one
//		 * of the constants defined by <code>SORT_COLUMN_</code>.
//		 */
//		private final int columnSelected;
//
//		/**
//		 * Constructs a new instance of <code>SortOrderSelectionListener</code>.
//		 * 
//		 * @param columnSelected
//		 *            The column to be given first priority in the sort order;
//		 *            this value should be one of the constants defined as
//		 *            <code>SORT_COLUMN_</code>.
//		 */
//		private SortOrderSelectionListener(final int columnSelected) {
//			this.columnSelected = columnSelected;
//		}
//
//		/*
//		 * (non-Javadoc)
//		 * 
//		 * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
//		 */
//		public void widgetSelected(SelectionEvent e) {
//			// Change the column titles.
//			final int oldSortIndex = sortOrder[0];
//			final TableColumn oldSortColumn = tableBindings
//					.getColumn(oldSortIndex);
//			oldSortColumn.setText(UNSORTED_COLUMN_NAMES[oldSortIndex]);
//			final TableColumn newSortColumn = tableBindings
//					.getColumn(columnSelected);
//			newSortColumn.setText(SORTED_COLUMN_NAMES[columnSelected]);
//
//			// Change the sort order.
//			boolean columnPlaced = false;
//			boolean enoughRoom = false;
//			int bumpedColumn = -1;
//			for (int i = 0; i < sortOrder.length; i++) {
//				if (sortOrder[i] == columnSelected) {
//					/*
//					 * We've found the place where the column existing in the
//					 * old sort order. No matter what at this point, we have
//					 * completed the reshuffling.
//					 */
//					enoughRoom = true;
//					if (bumpedColumn != -1) {
//						// We have already started bumping things around, so
//						// drop the last bumped column here.
//						sortOrder[i] = bumpedColumn;
//					} else {
//						// The order has not changed.
//						columnPlaced = true;
//					}
//					break;
//
//				} else if (columnPlaced) {
//					// We are currently bumping, so just bump another.
//					int temp = sortOrder[i];
//					sortOrder[i] = bumpedColumn;
//					bumpedColumn = temp;
//
//				} else {
//					/*
//					 * We are not currently bumping, so drop the column and
//					 * start bumping.
//					 */
//					bumpedColumn = sortOrder[i];
//					sortOrder[i] = columnSelected;
//					columnPlaced = true;
//				}
//			}
//
//			// Grow the sort order.
//			if (!enoughRoom) {
//				final int[] newSortOrder = new int[sortOrder.length + 1];
//				System.arraycopy(sortOrder, 0, newSortOrder, 0,
//						sortOrder.length);
//				newSortOrder[sortOrder.length] = bumpedColumn;
//				sortOrder = newSortOrder;
//			}
//
//			// Update the view tab.
//			updateViewTab();
//		}
//	}
//
//	/**
//	 * The data key for the binding stored on an SWT widget. The key is a
//	 * fully-qualified name, but in reverse order. This is so that the equals
//	 * method will detect misses faster.
//	 */
//	private static final String BINDING_KEY = "Binding.bindings.jface.eclipse.org"; //$NON-NLS-1$
//
//	/**
//	 * The image associate with a binding that exists as part of the system
//	 * definition.
//	 */
//	private static final Image IMAGE_BLANK = ImageFactory.getImage("blank"); //$NON-NLS-1$
//
//	/**
//	 * The image associated with a binding changed by the user.
//	 */
//	private static final Image IMAGE_CHANGE = ImageFactory.getImage("change"); //$NON-NLS-1$
//
//	/**
//	 * The data key at which the <code>Binding</code> instance for a table
//	 * item is stored.
//	 */
//	private static final String ITEM_DATA_KEY = "org.eclipse.jface.bindings"; //$NON-NLS-1$
//
//	/**
//	 * The number of items to show in the combo boxes.
//	 */
//	private static final int ITEMS_TO_SHOW = 9;
//
//	/**
//	 * The resource bundle from which translations can be retrieved.
//	 */
//	private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle
//			.getBundle(KeysPreferencePage.class.getName());
//
//	/**
//	 * The total number of columns on the view tab.
//	 */
//	private static final int VIEW_TOTAL_COLUMNS = 4;
//
//	/**
//	 * The translated names for the columns when they are the primary sort key
//	 * (e.g., ">Category<").
//	 */
//	private static final String[] SORTED_COLUMN_NAMES = new String[VIEW_TOTAL_COLUMNS];
//
//	/**
//	 * The index of the modify tab.
//	 * 
//	 * @since 3.1
//	 */
//	private static final int TAB_INDEX_MODIFY = 1;
//
//	/**
//	 * The translated names for the columns when they are not the primary sort
//	 * key (e.g., "Category").
//	 */
//	private static final String[] UNSORTED_COLUMN_NAMES = new String[VIEW_TOTAL_COLUMNS];
//
//	/**
//	 * The index of the column on the view tab containing the category name.
//	 */
//	private static final int VIEW_CATEGORY_COLUMN_INDEX = 0;
//
//	/**
//	 * The index of the column on the view tab containing the command name.
//	 */
//	private static final int VIEW_COMMAND_COLUMN_INDEX = 1;
//
//	/**
//	 * The index of the column on the view tab containing the context name.
//	 */
//	private static final int VIEW_CONTEXT_COLUMN_INDEX = 3;
//
//	/**
//	 * The index of the column on the view tab containing the key sequence.
//	 */
//	private static final int VIEW_KEY_SEQUENCE_COLUMN_INDEX = 2;
//
//	static {
//		UNSORTED_COLUMN_NAMES[VIEW_CATEGORY_COLUMN_INDEX] = Util
//				.translateString(RESOURCE_BUNDLE, "tableColumnCategory"); //$NON-NLS-1$
//		UNSORTED_COLUMN_NAMES[VIEW_COMMAND_COLUMN_INDEX] = Util
//				.translateString(RESOURCE_BUNDLE, "tableColumnCommand"); //$NON-NLS-1$
//		UNSORTED_COLUMN_NAMES[VIEW_KEY_SEQUENCE_COLUMN_INDEX] = Util
//				.translateString(RESOURCE_BUNDLE, "tableColumnKeySequence"); //$NON-NLS-1$
//		UNSORTED_COLUMN_NAMES[VIEW_CONTEXT_COLUMN_INDEX] = Util
//				.translateString(RESOURCE_BUNDLE, "tableColumnContext"); //$NON-NLS-1$
//
//		SORTED_COLUMN_NAMES[VIEW_CATEGORY_COLUMN_INDEX] = Util.translateString(
//				RESOURCE_BUNDLE, "tableColumnCategorySorted"); //$NON-NLS-1$
//		SORTED_COLUMN_NAMES[VIEW_COMMAND_COLUMN_INDEX] = Util.translateString(
//				RESOURCE_BUNDLE, "tableColumnCommandSorted"); //$NON-NLS-1$
//		SORTED_COLUMN_NAMES[VIEW_KEY_SEQUENCE_COLUMN_INDEX] = Util
//				.translateString(RESOURCE_BUNDLE,
//						"tableColumnKeySequenceSorted"); //$NON-NLS-1$
//		SORTED_COLUMN_NAMES[VIEW_CONTEXT_COLUMN_INDEX] = Util.translateString(
//				RESOURCE_BUNDLE, "tableColumnContextSorted"); //$NON-NLS-1$
//	}
//
//	/**
//	 * The workbench's activity manager. This activity manager is used to see if
//	 * certain commands should be filtered from the user interface.
//	 */
//	private IActivityManager activityManager;
//
//	/**
//	 * The workbench's binding service. This binding service is used to access
//	 * the current set of bindings, and to persist changes.
//	 */
//	private IBindingService bindingService;
//
//	/**
//	 * The add button located on the bottom left of the preference page. This
//	 * button adds the current trigger sequence to the currently selected
//	 * command.
//	 */
//	private Button buttonAdd;
//
//	/**
//	 * The remove button located on the bottom left of the preference page. This
//	 * button removes the current trigger sequence from the current command.
//	 */
//	private Button buttonRemove;
//
//	/**
//	 * The restore button located on the bottom left of the preference page.
//	 * This button attempts to restore the currently trigger sequence to its
//	 * initial (i.e., Binding.SYSTEM) state -- undoing all user modifications.
//	 */
//	private Button buttonRestore;
//
//	/**
//	 * A map of all the category identifiers indexed by the names that appear in
//	 * the user interface. This look-up table is built during initialization.
//	 */
//	private Map categoryIdsByUniqueName;
//
//	/**
//	 * A map of all the category names in the user interface indexed by their
//	 * identifiers. This look-up table is built during initialization.
//	 */
//	private Map categoryUniqueNamesById;
//
//	/**
//	 * The combo box containing the list of all categories for commands.
//	 */
//	private Combo comboCategory;
//
//	/**
//	 * The combo box containing the list of commands relevent for the currently
//	 * selected category.
//	 */
//	private Combo comboCommand;
//
//	/**
//	 * The combo box containing the list of contexts in the system.
//	 */
//	private Combo comboContext;
//
//	/**
//	 * The combo box containing the list of schemes in the system.
//	 */
//	private Combo comboScheme;
//
//	/**
//	 * A map of all the command identifiers indexed by the categories to which
//	 * they belong. This look-up table is built during initialization.
//	 */
//	private Map commandIdsByCategoryId;
//
//	/**
//	 * The parameterized commands corresponding to the current contents of
//	 * <code>comboCommand</code>. The commands in this array are in the same
//	 * order as in the combo. This value can be <code>null</code> if nothing
//	 * is selected in the combo.
//	 */
//	private ParameterizedCommand[] commands = null;
//
//	/**
//	 * The workbench's command service. This command service is used to access
//	 * the list of commands.
//	 */
//	private ICommandService commandService;
//
//	/**
//	 * A map of all the context identifiers indexed by the names that appear in
//	 * the user interface. This look-up table is built during initialization.
//	 */
//	private Map contextIdsByUniqueName;
//
//	/**
//	 * The workbench's context service. This context service is used to access
//	 * the list of contexts.
//	 */
//	private IContextService contextService;
//
//	/**
//	 * A map of all the category names in the user interface indexed by their
//	 * identifiers. This look-up table is built during initialization.
//	 */
//	private Map contextUniqueNamesById;
//
//	/**
//	 * The workbench's help system. This is used to register the page with the
//	 * help system.
//	 * 
//	 * TODO Add a help context
//	 */
//	// private IWorkbenchHelpSystem helpSystem;
//	/**
//	 * This is the label next to the table showing the bindings matching a
//	 * particular command. The label is disabled if there isn't a selected
//	 * command identifier.
//	 */
//	private Label labelBindingsForCommand;
//
//	/**
//	 * This is the label next to the table showing the bindings matching a
//	 * particular trigger sequence. The label is disabled if there isn't a
//	 * current key sequence.
//	 */
//	private Label labelBindingsForTriggerSequence;
//
//	/**
//	 * The label next to the context combo box. This label indicates whether the
//	 * context is a child of another context. If the current context is not a
//	 * child, then this label is blank.
//	 */
//	private Label labelContextExtends;
//
//	/**
//	 * The label next to the scheme combo box. This label indicates whether the
//	 * scheme is a child of another scheme. If the current scheme is not a
//	 * child, then this label is blank.
//	 */
//	private Label labelSchemeExtends;
//
//	/**
//	 * A binding manager local to this preference page. When the page is
//	 * initialized, the current bindings are read out from the binding service
//	 * and placed in this manager. This manager is then updated as the user
//	 * makes changes. When the user has finished, the contents of this manager
//	 * are compared with the contents of the binding service. The changes are
//	 * then persisted.
//	 */
//	private final BindingManager localChangeManager = new BindingManager(
//			new ContextManager(), new CommandManager());
//
//	/**
//	 * A map of all the scheme identifiers indexed by the names that appear in
//	 * the user interface. This look-up table is built during initialization.
//	 */
//	private Map schemeIdsByUniqueName;
//
//	/**
//	 * A map of all the scheme names in the user interface indexed by their
//	 * identifiers. This look-up table is built during initialization.
//	 */
//	private Map schemeUniqueNamesById;
//
//	/**
//	 * The sort order to be used on the view tab to display all of the key
//	 * bindings. This sort order can be changed by the user. This array is never
//	 * <code>null</code>, but may be empty.
//	 */
//	private int[] sortOrder = { VIEW_CATEGORY_COLUMN_INDEX,
//			VIEW_COMMAND_COLUMN_INDEX, VIEW_KEY_SEQUENCE_COLUMN_INDEX,
//			VIEW_CONTEXT_COLUMN_INDEX };
//
//	/**
//	 * The top-most tab folder for the preference page -- containing a view and
//	 * a modify tab.
//	 */
//	private TabFolder tabFolder;
//
//	/**
//	 * A table of the key bindings currently defined. This table appears on the
//	 * view tab; it is intended to be an easy way for users to learn the key
//	 * bindings in Eclipse. This value is only <code>null</code> until the
//	 * controls are first created.
//	 */
//	private Table tableBindings;
//
//	/**
//	 * The table containing all of the bindings matching the selected command.
//	 */
//	private Table tableBindingsForCommand;
//
//	/**
//	 * The table containing all of the bindings matching the current trigger
//	 * sequence.
//	 */
//	private Table tableBindingsForTriggerSequence;
//
//	/**
//	 * The text widget where keys are entered. This widget is managed by
//	 * <code>textTriggerSequenceManager</code>, which provides its special
//	 * behaviour.
//	 */
//	private Text textTriggerSequence;
//
//	/**
//	 * The manager for the text widget that traps incoming key events. This
//	 * manager should be used to access the widget, rather than accessing the
//	 * widget directly.
//	 */
//	private KeySequenceText textTriggerSequenceManager;
//
//	
//	/* (non-Javadoc)
//	 * @see org.eclipse.jface.preference.PreferencePage#applyData(java.lang.Object)
//	 */
//	public void applyData(Object data) {
//		if(data instanceof Binding) {
//			editBinding((Binding) data);
//		}
//	}
//	protected final Control createContents(final Composite parent) {
//		
//		PlatformUI.getWorkbench().getHelpSystem()
//			.setHelp(parent, IWorkbenchHelpContextIds.KEYS_PREFERENCE_PAGE);
//		
//		tabFolder = new TabFolder(parent, SWT.NULL);
//
//		// View tab
//		final TabItem viewTab = new TabItem(tabFolder, SWT.NULL);
//		viewTab.setText(Util.translateString(RESOURCE_BUNDLE, "viewTab.Text")); //$NON-NLS-1$
//		viewTab.setControl(createViewTab(tabFolder));
//
//		// Modify tab
//		final TabItem modifyTab = new TabItem(tabFolder, SWT.NULL);
//		modifyTab.setText(Util.translateString(RESOURCE_BUNDLE,
//				"modifyTab.Text")); //$NON-NLS-1$
//		modifyTab.setControl(createModifyTab(tabFolder));
//
//		// Do some fancy stuff.
//		applyDialogFont(tabFolder);
//		final IPreferenceStore store = getPreferenceStore();
//		final int selectedTab = store
//				.getInt(IPreferenceConstants.KEYS_PREFERENCE_SELECTED_TAB);
//		if ((tabFolder.getItemCount() > selectedTab) && (selectedTab > 0)) {
//			tabFolder.setSelection(selectedTab);
//		}
//		
//		return tabFolder;
//	}
//
//	/**
//	 * Creates the tab that allows the user to change the keyboard shortcuts.
//	 * 
//	 * @param parent
//	 *            The tab folder in which the tab should be created; must not be
//	 *            <code>null</code>.
//	 * @return The composite which represents the contents of the tab; never
//	 *         <code>null</code>.
//	 */
//	private final Composite createModifyTab(final TabFolder parent) {
//		final Composite composite = new Composite(parent, SWT.NULL);
//		composite.setLayout(new GridLayout());
//		GridData gridData = new GridData(GridData.FILL_BOTH);
//		composite.setLayoutData(gridData);
//		final Composite compositeKeyConfiguration = new Composite(composite,
//				SWT.NULL);
//		GridLayout gridLayout = new GridLayout();
//		gridLayout.numColumns = 3;
//		compositeKeyConfiguration.setLayout(gridLayout);
//		gridData = new GridData(GridData.FILL_HORIZONTAL);
//		compositeKeyConfiguration.setLayoutData(gridData);
//		final Label labelKeyConfiguration = new Label(
//				compositeKeyConfiguration, SWT.LEFT);
//		labelKeyConfiguration.setText(Util.translateString(RESOURCE_BUNDLE,
//				"labelScheme")); //$NON-NLS-1$
//		comboScheme = new Combo(compositeKeyConfiguration, SWT.READ_ONLY);
//		gridData = new GridData();
//		gridData.widthHint = 200;
//		comboScheme.setLayoutData(gridData);
//		comboScheme.setVisibleItemCount(ITEMS_TO_SHOW);
//
//		comboScheme.addSelectionListener(new SelectionAdapter() {
//			public final void widgetSelected(final SelectionEvent e) {
//				selectedComboScheme();
//			}
//		});
//
//		labelSchemeExtends = new Label(compositeKeyConfiguration, SWT.LEFT);
//		gridData = new GridData(GridData.FILL_HORIZONTAL);
//		labelSchemeExtends.setLayoutData(gridData);
//		final Control spacer = new Composite(composite, SWT.NULL);
//		gridData = new GridData();
//		gridData.heightHint = 10;
//		gridData.widthHint = 10;
//		spacer.setLayoutData(gridData);
//		final Group groupCommand = new Group(composite, SWT.SHADOW_NONE);
//		gridLayout = new GridLayout();
//		gridLayout.numColumns = 3;
//		groupCommand.setLayout(gridLayout);
//		gridData = new GridData(GridData.FILL_BOTH);
//		groupCommand.setLayoutData(gridData);
//		groupCommand.setText(Util.translateString(RESOURCE_BUNDLE,
//				"groupCommand")); //$NON-NLS-1$	
//		final Label labelCategory = new Label(groupCommand, SWT.LEFT);
//		gridData = new GridData();
//		labelCategory.setLayoutData(gridData);
//		labelCategory.setText(Util.translateString(RESOURCE_BUNDLE,
//				"labelCategory")); //$NON-NLS-1$
//		comboCategory = new Combo(groupCommand, SWT.READ_ONLY);
//		gridData = new GridData();
//		gridData.horizontalSpan = 2;
//		gridData.widthHint = 200;
//		comboCategory.setLayoutData(gridData);
//		comboCategory.setVisibleItemCount(ITEMS_TO_SHOW);
//
//		comboCategory.addSelectionListener(new SelectionAdapter() {
//			public final void widgetSelected(final SelectionEvent e) {
//				update();
//			}
//		});
//
//		final Label labelCommand = new Label(groupCommand, SWT.LEFT);
//		gridData = new GridData();
//		labelCommand.setLayoutData(gridData);
//		labelCommand.setText(Util.translateString(RESOURCE_BUNDLE,
//				"labelCommand")); //$NON-NLS-1$
//		comboCommand = new Combo(groupCommand, SWT.READ_ONLY);
//		gridData = new GridData();
//		gridData.horizontalSpan = 2;
//		gridData.widthHint = 300;
//		comboCommand.setLayoutData(gridData);
//		comboCommand.setVisibleItemCount(9);
//
//		comboCommand.addSelectionListener(new SelectionAdapter() {
//			public final void widgetSelected(final SelectionEvent e) {
//				update();
//			}
//		});
//
//		labelBindingsForCommand = new Label(groupCommand, SWT.LEFT);
//		gridData = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
//		gridData.verticalAlignment = GridData.FILL_VERTICAL;
//		labelBindingsForCommand.setLayoutData(gridData);
//		labelBindingsForCommand.setText(Util.translateString(RESOURCE_BUNDLE,
//				"labelAssignmentsForCommand")); //$NON-NLS-1$
//		tableBindingsForCommand = new Table(groupCommand, SWT.BORDER
//				| SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL);
//		tableBindingsForCommand.setHeaderVisible(true);
//		gridData = new GridData(GridData.FILL_BOTH);
//		gridData.heightHint = 60;
//		gridData.horizontalSpan = 2;
//		boolean isMac = org.eclipse.jface.util.Util.isMac();
//		gridData.widthHint =  isMac ? 620 : 520;
//		tableBindingsForCommand.setLayoutData(gridData);
//		TableColumn tableColumnDelta = new TableColumn(tableBindingsForCommand,
//				SWT.NULL, 0);
//		tableColumnDelta.setResizable(false);
//		tableColumnDelta.setText(Util.ZERO_LENGTH_STRING);
//		tableColumnDelta.setWidth(20);
//		TableColumn tableColumnContext = new TableColumn(
//				tableBindingsForCommand, SWT.NULL, 1);
//		tableColumnContext.setResizable(true);
//		tableColumnContext.setText(Util.translateString(RESOURCE_BUNDLE,
//				"tableColumnContext")); //$NON-NLS-1$
//		tableColumnContext.pack();
//		tableColumnContext.setWidth(200);
//		final TableColumn tableColumnKeySequence = new TableColumn(
//				tableBindingsForCommand, SWT.NULL, 2);
//		tableColumnKeySequence.setResizable(true);
//		tableColumnKeySequence.setText(Util.translateString(RESOURCE_BUNDLE,
//				"tableColumnKeySequence")); //$NON-NLS-1$
//		tableColumnKeySequence.pack();
//		tableColumnKeySequence.setWidth(300);
//
//		tableBindingsForCommand.addMouseListener(new MouseAdapter() {
//
//			public void mouseDoubleClick(MouseEvent mouseEvent) {
//				update();
//			}
//		});
//
//		tableBindingsForCommand.addSelectionListener(new SelectionAdapter() {
//
//			public void widgetSelected(SelectionEvent selectionEvent) {
//				selectedTableBindingsForCommand();
//			}
//		});
//
//		final Group groupKeySequence = new Group(composite, SWT.SHADOW_NONE);
//		gridLayout = new GridLayout();
//		gridLayout.numColumns = 4;
//		groupKeySequence.setLayout(gridLayout);
//		gridData = new GridData(GridData.FILL_BOTH);
//		groupKeySequence.setLayoutData(gridData);
//		groupKeySequence.setText(Util.translateString(RESOURCE_BUNDLE,
//				"groupKeySequence")); //$NON-NLS-1$	
//		final Label labelKeySequence = new Label(groupKeySequence, SWT.LEFT);
//		gridData = new GridData();
//		labelKeySequence.setLayoutData(gridData);
//		labelKeySequence.setText(Util.translateString(RESOURCE_BUNDLE,
//				"labelKeySequence")); //$NON-NLS-1$
//
//		// The text widget into which the key strokes will be entered.
//		textTriggerSequence = new Text(groupKeySequence, SWT.BORDER);
//		// On MacOS X, this font will be changed by KeySequenceText
//		textTriggerSequence.setFont(groupKeySequence.getFont());
//		gridData = new GridData();
//		gridData.horizontalSpan = 2;
//		gridData.widthHint = 300;
//		textTriggerSequence.setLayoutData(gridData);
//		textTriggerSequence.addModifyListener(new ModifyListener() {
//			public void modifyText(ModifyEvent e) {
//				update();
//			}
//		});
//		textTriggerSequence.addFocusListener(new FocusListener() {
//			public void focusGained(FocusEvent e) {
//				bindingService.setKeyFilterEnabled(false);
//			}
//
//			public void focusLost(FocusEvent e) {
//				bindingService.setKeyFilterEnabled(true);
//			}
//		});
//		textTriggerSequence.addDisposeListener(new DisposeListener() {
//			public void widgetDisposed(DisposeEvent e) {
//				if (!bindingService.isKeyFilterEnabled()) {
//					bindingService.setKeyFilterEnabled(true);
//				}
//			}
//		});
//
//		// The manager for the key sequence text widget.
//		textTriggerSequenceManager = new KeySequenceText(textTriggerSequence);
//		textTriggerSequenceManager.setKeyStrokeLimit(4);
//
//		// Button for adding trapped key strokes
//		final Button buttonAddKey = new Button(groupKeySequence, SWT.LEFT
//				| SWT.ARROW);
//		buttonAddKey.setToolTipText(Util.translateString(RESOURCE_BUNDLE,
//				"buttonAddKey.ToolTipText")); //$NON-NLS-1$
//		gridData = new GridData();
//		gridData.heightHint = comboCategory.getTextHeight();
//		buttonAddKey.setLayoutData(gridData);
//
//		// Arrow buttons aren't normally added to the tab list. Let's fix that.
//		final Control[] tabStops = groupKeySequence.getTabList();
//		final ArrayList newTabStops = new ArrayList();
//		for (int i = 0; i < tabStops.length; i++) {
//			Control tabStop = tabStops[i];
//			newTabStops.add(tabStop);
//			if (textTriggerSequence.equals(tabStop)) {
//				newTabStops.add(buttonAddKey);
//			}
//		}
//		final Control[] newTabStopArray = (Control[]) newTabStops
//				.toArray(new Control[newTabStops.size()]);
//		groupKeySequence.setTabList(newTabStopArray);
//
//		// Construct the menu to attach to the above button.
//		final Menu menuButtonAddKey = new Menu(buttonAddKey);
//		final Iterator trappedKeyItr = KeySequenceText.TRAPPED_KEYS.iterator();
//		while (trappedKeyItr.hasNext()) {
//			final KeyStroke trappedKey = (KeyStroke) trappedKeyItr.next();
//			final MenuItem menuItem = new MenuItem(menuButtonAddKey, SWT.PUSH);
//			menuItem.setText(trappedKey.format());
//			menuItem.addSelectionListener(new SelectionAdapter() {
//
//				public void widgetSelected(SelectionEvent e) {
//					textTriggerSequenceManager.insert(trappedKey);
//					textTriggerSequence.setFocus();
//					textTriggerSequence.setSelection(textTriggerSequence
//							.getTextLimit());
//				}
//			});
//		}
//		buttonAddKey.addSelectionListener(new SelectionAdapter() {
//
//			public void widgetSelected(SelectionEvent selectionEvent) {
//				Point buttonLocation = buttonAddKey.getLocation();
//				buttonLocation = groupKeySequence.toDisplay(buttonLocation.x,
//						buttonLocation.y);
//				Point buttonSize = buttonAddKey.getSize();
//				menuButtonAddKey.setLocation(buttonLocation.x, buttonLocation.y
//						+ buttonSize.y);
//				menuButtonAddKey.setVisible(true);
//			}
//		});
//
//		labelBindingsForTriggerSequence = new Label(groupKeySequence, SWT.LEFT);
//		gridData = new GridData(GridData.VERTICAL_ALIGN_BEGINNING);
//		gridData.verticalAlignment = GridData.FILL_VERTICAL;
//		labelBindingsForTriggerSequence.setLayoutData(gridData);
//		labelBindingsForTriggerSequence.setText(Util.translateString(
//				RESOURCE_BUNDLE, "labelAssignmentsForKeySequence")); //$NON-NLS-1$
//		tableBindingsForTriggerSequence = new Table(groupKeySequence,
//				SWT.BORDER | SWT.FULL_SELECTION | SWT.H_SCROLL | SWT.V_SCROLL);
//		tableBindingsForTriggerSequence.setHeaderVisible(true);
//		gridData = new GridData(GridData.FILL_BOTH);
//		gridData.heightHint = 60;
//		gridData.horizontalSpan = 3;
//		gridData.widthHint = isMac ? 620 : 520;
//		tableBindingsForTriggerSequence.setLayoutData(gridData);
//		tableColumnDelta = new TableColumn(tableBindingsForTriggerSequence,
//				SWT.NULL, 0);
//		tableColumnDelta.setResizable(false);
//		tableColumnDelta.setText(Util.ZERO_LENGTH_STRING);
//		tableColumnDelta.setWidth(20);
//		tableColumnContext = new TableColumn(tableBindingsForTriggerSequence,
//				SWT.NULL, 1);
//		tableColumnContext.setResizable(true);
//		tableColumnContext.setText(Util.translateString(RESOURCE_BUNDLE,
//				"tableColumnContext")); //$NON-NLS-1$
//		tableColumnContext.pack();
//		tableColumnContext.setWidth(200);
//		final TableColumn tableColumnCommand = new TableColumn(
//				tableBindingsForTriggerSequence, SWT.NULL, 2);
//		tableColumnCommand.setResizable(true);
//		tableColumnCommand.setText(Util.translateString(RESOURCE_BUNDLE,
//				"tableColumnCommand")); //$NON-NLS-1$
//		tableColumnCommand.pack();
//		tableColumnCommand.setWidth(300);
//
//		tableBindingsForTriggerSequence.addMouseListener(new MouseAdapter() {
//
//			public void mouseDoubleClick(MouseEvent mouseEvent) {
//				update();
//			}
//		});
//
//		tableBindingsForTriggerSequence
//				.addSelectionListener(new SelectionAdapter() {
//
//					public void widgetSelected(SelectionEvent selectionEvent) {
//						selectedTableBindingsForTriggerSequence();
//					}
//				});
//
//		final Composite compositeContext = new Composite(composite, SWT.NULL);
//		gridLayout = new GridLayout();
//		gridLayout.numColumns = 3;
//		compositeContext.setLayout(gridLayout);
//		gridData = new GridData(GridData.FILL_HORIZONTAL);
//		compositeContext.setLayoutData(gridData);
//		final Label labelContext = new Label(compositeContext, SWT.LEFT);
//		labelContext.setText(Util.translateString(RESOURCE_BUNDLE,
//				"labelContext")); //$NON-NLS-1$
//		comboContext = new Combo(compositeContext, SWT.READ_ONLY);
//		gridData = new GridData();
//		gridData.widthHint = 250;
//		comboContext.setLayoutData(gridData);
//		comboContext.setVisibleItemCount(ITEMS_TO_SHOW);
//
//		comboContext.addSelectionListener(new SelectionAdapter() {
//			public final void widgetSelected(final SelectionEvent e) {
//				update();
//			}
//		});
//
//		labelContextExtends = new Label(compositeContext, SWT.LEFT);
//		gridData = new GridData(GridData.FILL_HORIZONTAL);
//		labelContextExtends.setLayoutData(gridData);
//		final Composite compositeButton = new Composite(composite, SWT.NULL);
//		gridLayout = new GridLayout();
//		gridLayout.marginHeight = 20;
//		gridLayout.marginWidth = 0;
//		gridLayout.numColumns = 3;
//		compositeButton.setLayout(gridLayout);
//		gridData = new GridData();
//		compositeButton.setLayoutData(gridData);
//		buttonAdd = new Button(compositeButton, SWT.CENTER | SWT.PUSH);
//		gridData = new GridData();
//		int widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
//		buttonAdd.setText(Util.translateString(RESOURCE_BUNDLE, "buttonAdd")); //$NON-NLS-1$
//		gridData.widthHint = Math.max(widthHint, buttonAdd.computeSize(
//				SWT.DEFAULT, SWT.DEFAULT, true).x) + 5;
//		buttonAdd.setLayoutData(gridData);
//
//		buttonAdd.addSelectionListener(new SelectionAdapter() {
//
//			public void widgetSelected(SelectionEvent selectionEvent) {
//				selectedButtonAdd();
//			}
//		});
//
//		buttonRemove = new Button(compositeButton, SWT.CENTER | SWT.PUSH);
//		gridData = new GridData();
//		widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
//		buttonRemove.setText(Util.translateString(RESOURCE_BUNDLE,
//				"buttonRemove")); //$NON-NLS-1$
//		gridData.widthHint = Math.max(widthHint, buttonRemove.computeSize(
//				SWT.DEFAULT, SWT.DEFAULT, true).x) + 5;
//		buttonRemove.setLayoutData(gridData);
//
//		buttonRemove.addSelectionListener(new SelectionAdapter() {
//
//			public void widgetSelected(SelectionEvent selectionEvent) {
//				selectedButtonRemove();
//			}
//		});
//
//		buttonRestore = new Button(compositeButton, SWT.CENTER | SWT.PUSH);
//		gridData = new GridData();
//		widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
//		buttonRestore.setText(Util.translateString(RESOURCE_BUNDLE,
//				"buttonRestore")); //$NON-NLS-1$
//		gridData.widthHint = Math.max(widthHint, buttonRestore.computeSize(
//				SWT.DEFAULT, SWT.DEFAULT, true).x) + 5;
//		buttonRestore.setLayoutData(gridData);
//
//		buttonRestore.addSelectionListener(new SelectionAdapter() {
//
//			public void widgetSelected(SelectionEvent selectionEvent) {
//				selectedButtonRestore();
//			}
//		});
//
//		return composite;
//	}
//
//	/**
//	 * Creates a tab on the main page for displaying an uneditable list of the
//	 * current key bindings. This is intended as a discovery tool for new users.
//	 * It shows all of the key bindings for the current key configuration,
//	 * platform and locale.
//	 * 
//	 * @param parent
//	 *            The tab folder in which the tab should be created; must not be
//	 *            <code>null</code>.
//	 * @return The newly created composite containing all of the controls; never
//	 *         <code>null</code>.
//	 * @since 3.1
//	 */
//	private final Composite createViewTab(final TabFolder parent) {
//		GridData gridData = null;
//		int widthHint;
//
//		// Create the composite for the tab.
//		final Composite composite = new Composite(parent, SWT.NONE);
//		composite.setLayoutData(new GridData(GridData.FILL_BOTH));
//		composite.setLayout(new GridLayout());
//
//		// Place a table inside the tab.
//		tableBindings = new Table(composite, SWT.BORDER | SWT.FULL_SELECTION
//				| SWT.H_SCROLL | SWT.V_SCROLL);
//		tableBindings.setHeaderVisible(true);
//		gridData = new GridData(GridData.FILL_BOTH);
//		gridData.heightHint = 400;
//		gridData.horizontalSpan = 2;
//		tableBindings.setLayoutData(gridData);
//		final TableColumn tableColumnCategory = new TableColumn(tableBindings,
//				SWT.NONE, VIEW_CATEGORY_COLUMN_INDEX);
//		tableColumnCategory
//				.setText(SORTED_COLUMN_NAMES[VIEW_CATEGORY_COLUMN_INDEX]);
//		tableColumnCategory
//				.addSelectionListener(new SortOrderSelectionListener(
//						VIEW_CATEGORY_COLUMN_INDEX));
//		final TableColumn tableColumnCommand = new TableColumn(tableBindings,
//				SWT.NONE, VIEW_COMMAND_COLUMN_INDEX);
//		tableColumnCommand
//				.setText(UNSORTED_COLUMN_NAMES[VIEW_COMMAND_COLUMN_INDEX]);
//		tableColumnCommand.addSelectionListener(new SortOrderSelectionListener(
//				VIEW_COMMAND_COLUMN_INDEX));
//		final TableColumn tableColumnKeySequence = new TableColumn(
//				tableBindings, SWT.NONE, VIEW_KEY_SEQUENCE_COLUMN_INDEX);
//		tableColumnKeySequence
//				.setText(UNSORTED_COLUMN_NAMES[VIEW_KEY_SEQUENCE_COLUMN_INDEX]);
//		tableColumnKeySequence
//				.addSelectionListener(new SortOrderSelectionListener(
//						VIEW_KEY_SEQUENCE_COLUMN_INDEX));
//		final TableColumn tableColumnContext = new TableColumn(tableBindings,
//				SWT.NONE, VIEW_CONTEXT_COLUMN_INDEX);
//		tableColumnContext
//				.setText(UNSORTED_COLUMN_NAMES[VIEW_CONTEXT_COLUMN_INDEX]);
//		tableColumnContext.addSelectionListener(new SortOrderSelectionListener(
//				VIEW_CONTEXT_COLUMN_INDEX));
//		tableBindings.addSelectionListener(new SelectionAdapter() {
//			public final void widgetDefaultSelected(final SelectionEvent e) {
//				selectedTableKeyBindings();
//			}
//		});
//
//		// A composite for the buttons.
//		final Composite buttonBar = new Composite(composite, SWT.NONE);
//		buttonBar.setLayout(new GridLayout(2, false));
//		gridData = new GridData();
//		gridData.horizontalAlignment = GridData.END;
//		buttonBar.setLayoutData(gridData);
//
//		// A button for editing the current selection.
//		final Button editButton = new Button(buttonBar, SWT.PUSH);
//		gridData = new GridData();
//		widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
//		editButton.setText(Util.translateString(RESOURCE_BUNDLE, "buttonEdit")); //$NON-NLS-1$
//		gridData.widthHint = Math.max(widthHint, editButton.computeSize(
//				SWT.DEFAULT, SWT.DEFAULT, true).x) + 5;
//		editButton.setLayoutData(gridData);
//		editButton.addSelectionListener(new SelectionListener() {
//
//			/*
//			 * (non-Javadoc)
//			 * 
//			 * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
//			 */
//			public final void widgetDefaultSelected(final SelectionEvent event) {
//				selectedTableKeyBindings();
//			}
//
//			/*
//			 * (non-Javadoc)
//			 * 
//			 * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
//			 */
//			public void widgetSelected(SelectionEvent e) {
//				widgetDefaultSelected(e);
//			}
//		});
//
//		// A button for exporting the contents to a file.
//		final Button buttonExport = new Button(buttonBar, SWT.PUSH);
//		gridData = new GridData();
//		widthHint = convertHorizontalDLUsToPixels(IDialogConstants.BUTTON_WIDTH);
//		buttonExport.setText(Util.translateString(RESOURCE_BUNDLE,
//				"buttonExport")); //$NON-NLS-1$
//		gridData.widthHint = Math.max(widthHint, buttonExport.computeSize(
//				SWT.DEFAULT, SWT.DEFAULT, true).x) + 5;
//		buttonExport.setLayoutData(gridData);
//		buttonExport.addSelectionListener(new SelectionListener() {
//
//			/*
//			 * (non-Javadoc)
//			 * 
//			 * @see org.eclipse.swt.events.SelectionListener#widgetDefaultSelected(org.eclipse.swt.events.SelectionEvent)
//			 */
//			public final void widgetDefaultSelected(final SelectionEvent event) {
//				selectedButtonExport();
//			}
//
//			/*
//			 * (non-Javadoc)
//			 * 
//			 * @see org.eclipse.swt.events.SelectionListener#widgetSelected(org.eclipse.swt.events.SelectionEvent)
//			 */
//			public void widgetSelected(SelectionEvent e) {
//				widgetDefaultSelected(e);
//			}
//		});
//
//		return composite;
//	}
//
//	protected IPreferenceStore doGetPreferenceStore() {
//		return PrefUtil.getInternalPreferenceStore();
//	}
//
//	/**
//	 * Allows the user to change the key bindings for a particular command.
//	 * Switches the tab to the modify tab, and then selects the category and
//	 * command that corresponds with the given command name. It then selects the
//	 * given key sequence and gives focus to the key sequence text widget.
//	 * 
//	 * @param binding
//	 *            The binding to be edited; if <code>null</code>, then just
//	 *            switch to the modify tab. If the <code>binding</code> does
//	 *            not correspond to anything in the keys preference page, then
//	 *            this also just switches to the modify tab.
//	 * @since 3.1
//	 */
//	public final void editBinding(final Binding binding) {
//		// Switch to the modify tab.
//		tabFolder.setSelection(TAB_INDEX_MODIFY);
//
//		// If there is no command name, stop here.
//		if (binding == null) {
//			return;
//		}
//
//		/*
//		 * Get the corresponding category and command names. If either is
//		 * undefined, then we can just stop now. We won't be able to find their
//		 * name.
//		 */
//		final ParameterizedCommand command = binding.getParameterizedCommand();
//		String categoryName = null;
//		String commandName = null;
//		try {
//			categoryName = command.getCommand().getCategory().getName();
//			commandName = command.getName();
//		} catch (final NotDefinedException e) {
//			return; // no name
//		}
//
//		// Update the category combo box.
//		final String[] categoryNames = comboCategory.getItems();
//		int i = 0;
//		for (; i < categoryNames.length; i++) {
//			if (categoryName.equals(categoryNames[i])) {
//				break;
//			}
//		}
//		if (i >= comboCategory.getItemCount()) {
//			// Couldn't find the category, so abort.
//			return;
//		}
//		comboCategory.select(i);
//
//		// Update the commands combo box.
//		updateComboCommand();
//
//		// Update the command combo box.
//		final String[] commandNames = comboCommand.getItems();
//		int j = 0;
//		for (; j < commandNames.length; j++) {
//			if (commandName.equals(commandNames[j])) {
//				if (comboCommand.getSelectionIndex() != j) {
//					comboCommand.select(j);
//				}
//				break;
//			}
//		}
//		if (j >= comboCommand.getItemCount()) {
//			// Couldn't find the command, so just select the first and then stop
//			if (comboCommand.getSelectionIndex() != 0) {
//				comboCommand.select(0);
//			}
//			update();
//			return;
//		}
//
//		/*
//		 * Update and validate the state of the modify tab in response to these
//		 * selection changes.
//		 */
//		update();
//
//		// Select the right key binding, if possible.
//		final TableItem[] items = tableBindingsForCommand.getItems();
//		int k = 0;
//		for (; k < items.length; k++) {
//			final String currentKeySequence = items[k].getText(2);
//			if (binding.getTriggerSequence().format()
//					.equals(currentKeySequence)) {
//				break;
//			}
//		}
//		if (k < tableBindingsForCommand.getItemCount()) {
//			tableBindingsForCommand.select(k);
//			tableBindingsForCommand.notifyListeners(SWT.Selection, null);
//			textTriggerSequence.setFocus();
//		}
//	}
//
//	/**
//	 * Returns the identifier for the currently selected category.
//	 * 
//	 * @return The selected category; <code>null</code> if none.
//	 */
//	private final String getCategoryId() {
//		return !commandIdsByCategoryId.containsKey(null)
//				|| comboCategory.getSelectionIndex() > 0 ? (String) categoryIdsByUniqueName
//				.get(comboCategory.getText())
//				: null;
//	}
//
//	/**
//	 * Returns the identifier for the currently selected context.
//	 * 
//	 * @return The selected context; <code>null</code> if none.
//	 */
//	private final String getContextId() {
//		return comboContext.getSelectionIndex() >= 0 ? (String) contextIdsByUniqueName
//				.get(comboContext.getText())
//				: null;
//	}
//
//	/**
//	 * Returns the current trigger sequence.
//	 * 
//	 * @return The trigger sequence; may be empty, but never <code>null</code>.
//	 */
//	private final KeySequence getKeySequence() {
//		return textTriggerSequenceManager.getKeySequence();
//	}
//
//	/**
//	 * Returns the currently-selected fully-parameterized command.
//	 * 
//	 * @return The selected fully-parameterized command; <code>null</code> if
//	 *         none.
//	 */
//	private final ParameterizedCommand getParameterizedCommand() {
//		final int selectionIndex = comboCommand.getSelectionIndex();
//		if ((selectionIndex >= 0) && (commands != null)
//				&& (selectionIndex < commands.length)) {
//			return commands[selectionIndex];
//		}
//
//		return null;
//	}
//
//	/**
//	 * Returns the identifier for the currently selected scheme.
//	 * 
//	 * @return The selected scheme; <code>null</code> if none.
//	 */
//	private final String getSchemeId() {
//		return comboScheme.getSelectionIndex() >= 0 ? (String) schemeIdsByUniqueName
//				.get(comboScheme.getText())
//				: null;
//	}
//
//	public final void init(final IWorkbench workbench) {
//		activityManager = workbench.getActivitySupport().getActivityManager();
//		bindingService = (IBindingService) workbench.getService(IBindingService.class);
//		commandService = (ICommandService) workbench.getService(ICommandService.class);
//		contextService = (IContextService) workbench.getService(IContextService.class);
//	}
//
//	/**
//	 * Checks whether the activity manager knows anything about this command
//	 * identifier. If the activity manager is currently filtering this command,
//	 * then it does not appear in the user interface.
//	 * 
//	 * @param command
//	 *            The command which should be checked against the activities;
//	 *            must not be <code>null</code>.
//	 * @return <code>true</code> if the command identifier is not filtered;
//	 *         <code>false</code> if it is
//	 */
//	private final boolean isActive(final Command command) {
//		return activityManager.getIdentifier(command.getId()).isEnabled();
//	}
//
//	/**
//	 * Logs the given exception, and opens an error dialog saying that something
//	 * went wrong. The exception is assumed to have something to do with the
//	 * preference store.
//	 * 
//	 * @param exception
//	 *            The exception to be logged; must not be <code>null</code>.
//	 */
//	private final void logPreferenceStoreException(final Throwable exception) {
//		final String message = Util.translateString(RESOURCE_BUNDLE,
//				"PreferenceStoreError.Message"); //$NON-NLS-1$
//		String exceptionMessage = exception.getMessage();
//		if (exceptionMessage == null) {
//			exceptionMessage = message;
//		}
//		final IStatus status = new Status(IStatus.ERROR,
//				WorkbenchPlugin.PI_WORKBENCH, 0, exceptionMessage, exception);
//		WorkbenchPlugin.log(message, status);
//		StatusUtil.handleStatus(message, exception, StatusManager.SHOW);
//	}
//
//	public final boolean performCancel() {
//		// Save the selected tab for future reference.
//		persistSelectedTab();
//
//		return super.performCancel();
//	}
//
//	protected final void performDefaults() {
//		// Ask the user to confirm
//		final String title = Util.translateString(RESOURCE_BUNDLE,
//				"restoreDefaultsMessageBoxText"); //$NON-NLS-1$
//		final String message = Util.translateString(RESOURCE_BUNDLE,
//				"restoreDefaultsMessageBoxMessage"); //$NON-NLS-1$
//		final boolean confirmed = MessageDialog.open(MessageDialog.CONFIRM,
//				getShell(), title, message, SWT.SHEET);
//
//		if (confirmed) {
//			// Fix the scheme in the local changes.
//			final String defaultSchemeId = bindingService.getDefaultSchemeId();
//			final Scheme defaultScheme = localChangeManager
//					.getScheme(defaultSchemeId);
//			try {
//				localChangeManager.setActiveScheme(defaultScheme);
//			} catch (final NotDefinedException e) {
//				// At least we tried....
//			}
//
//			// Fix the bindings in the local changes.
//			final Binding[] currentBindings = localChangeManager.getBindings();
//			final int currentBindingsLength = currentBindings.length;
//			final Set trimmedBindings = new HashSet();
//			for (int i = 0; i < currentBindingsLength; i++) {
//				final Binding binding = currentBindings[i];
//				if (binding.getType() != Binding.USER) {
//					trimmedBindings.add(binding);
//				}
//			}
//			final Binding[] trimmedBindingArray = (Binding[]) trimmedBindings
//					.toArray(new Binding[trimmedBindings.size()]);
//			localChangeManager.setBindings(trimmedBindingArray);
//
//			// Apply the changes.
//			try {
//				bindingService.savePreferences(defaultScheme,
//						trimmedBindingArray);
//			} catch (final IOException e) {
//				logPreferenceStoreException(e);
//			}
//		}
//
//		setScheme(localChangeManager.getActiveScheme()); // update the scheme
//		update(true);
//		super.performDefaults();
//	}
//
//	public final boolean performOk() {
//		// Save the preferences.
//		try {
//			bindingService.savePreferences(
//					localChangeManager.getActiveScheme(), localChangeManager
//							.getBindings());
//		} catch (final IOException e) {
//			logPreferenceStoreException(e);
//		}
//
//		// Save the selected tab for future reference.
//		persistSelectedTab();
//
//		return super.performOk();
//	}
//
//	/**
//	 * Remembers the currently selected tab for when the preference page next
//	 * opens.
//	 */
//	private final void persistSelectedTab() {
//		final IPreferenceStore store = getPreferenceStore();
//		store.setValue(IPreferenceConstants.KEYS_PREFERENCE_SELECTED_TAB,
//				tabFolder.getSelectionIndex());
//	}
//
//	/**
//	 * Handles the selection event on the add button. This removes all
//	 * user-defined bindings matching the given key sequence, scheme and
//	 * context. It then adds a new binding with the current selections.
//	 */
//	private final void selectedButtonAdd() {
//		final ParameterizedCommand command = getParameterizedCommand();
//		final String contextId = getContextId();
//		final String schemeId = getSchemeId();
//		final KeySequence keySequence = getKeySequence();
//		localChangeManager.removeBindings(keySequence, schemeId, contextId,
//				null, null, null, Binding.USER);
//		localChangeManager.addBinding(new KeyBinding(keySequence, command,
//				schemeId, contextId, null, null, null, Binding.USER));
//		update(true);
//	}
//
//	/**
//	 * Provides a facility for exporting the viewable list of key bindings to a
//	 * file. Currently, this only supports exporting to a list of
//	 * comma-separated values. The user is prompted for which file should
//	 * receive our bounty.
//	 * 
//	 * @since 3.1
//	 */
//	private final void selectedButtonExport() {
//		final FileDialog fileDialog = new FileDialog(getShell(), SWT.SAVE
//				| SWT.SHEET);
//		fileDialog.setFilterExtensions(new String[] { "*.csv" }); //$NON-NLS-1$
//		fileDialog.setFilterNames(new String[] { Util.translateString(
//				RESOURCE_BUNDLE, "csvFilterName") }); //$NON-NLS-1$
//		final String filePath = fileDialog.open();
//		if (filePath == null) {
//			return;
//		}
//
//		final SafeRunnable runnable = new SafeRunnable() {
//			public final void run() throws IOException {
//				Writer fileWriter = null;
//				try {
//					fileWriter = new BufferedWriter(new FileWriter(filePath));
//					final TableItem[] items = tableBindings.getItems();
//					final int numColumns = tableBindings.getColumnCount();
//					for (int i = 0; i < items.length; i++) {
//						final TableItem item = items[i];
//						for (int j = 0; j < numColumns; j++) {
//							String buf = Util.replaceAll(item.getText(j), "\"", //$NON-NLS-1$
//									"\"\""); //$NON-NLS-1$
//							fileWriter.write("\"" + buf + "\"");  //$NON-NLS-1$//$NON-NLS-2$
//							if (j < numColumns - 1) {
//								fileWriter.write(',');
//							}
//						}
//						fileWriter.write(System.getProperty("line.separator")); //$NON-NLS-1$
//					}
//
//				} finally {
//					if (fileWriter != null) {
//						try {
//							fileWriter.close();
//						} catch (final IOException e) {
//							// At least I tried.
//						}
//					}
//
//				}
//			}
//		};
//		SafeRunner.run(runnable);
//	}
//	
//	/**
//	 * Handles the selection event on the remove button. This removes all
//	 * user-defined bindings matching the given key sequence, scheme and
//	 * context. It then adds a new deletion binding for the selected trigger
//	 * sequence.
//	 */
//	private final void selectedButtonRemove() {
//		final String contextId = getContextId();
//		final String schemeId = getSchemeId();
//		final KeySequence keySequence = getKeySequence();
//		localChangeManager.removeBindings(keySequence, schemeId, contextId,
//				null, null, null, Binding.USER);
//		localChangeManager.addBinding(new KeyBinding(keySequence, null,
//				schemeId, contextId, null, null, null, Binding.USER));
//		update(true);
//	}
//
//	/**
//	 * Handles the selection event on the restore button. This removes all
//	 * user-defined bindings matching the given key sequence, scheme and
//	 * context.
//	 */
//	private final void selectedButtonRestore() {
//		String contextId = getContextId();
//		String schemeId = getSchemeId();
//		KeySequence keySequence = getKeySequence();
//		localChangeManager.removeBindings(keySequence, schemeId, contextId,
//				null, null, null, Binding.USER);
//		update(true);
//	}
//
//	/**
//	 * Updates the local managers active scheme, and then updates the interface.
//	 */
//	private final void selectedComboScheme() {
//		final String activeSchemeId = getSchemeId();
//		final Scheme activeScheme = localChangeManager
//				.getScheme(activeSchemeId);
//		try {
//			localChangeManager.setActiveScheme(activeScheme);
//		} catch (final NotDefinedException e) {
//			// Oh, well.
//		}
//		update(true);
//	}
//
//	/**
//	 * Handles the selection event on the table containing the bindings for a
//	 * particular command. This updates the context and trigger sequence based
//	 * on the selected binding.
//	 */
//	private final void selectedTableBindingsForCommand() {
//		final int selection = tableBindingsForCommand.getSelectionIndex();
//		if ((selection >= 0)
//				&& (selection < tableBindingsForCommand.getItemCount())) {
//			final TableItem item = tableBindingsForCommand.getItem(selection);
//			final KeyBinding binding = (KeyBinding) item.getData(ITEM_DATA_KEY);
//			setContextId(binding.getContextId());
//			setKeySequence(binding.getKeySequence());
//		}
//
//		update();
//	}
//
//	/**
//	 * Handles the selection event on the table containing the bindings for a
//	 * particular trigger sequence. This updates the context based on the
//	 * selected binding.
//	 */
//	private final void selectedTableBindingsForTriggerSequence() {
//		final int selection = tableBindingsForTriggerSequence
//				.getSelectionIndex();
//		if ((selection >= 0)
//				&& (selection < tableBindingsForTriggerSequence.getItemCount())) {
//			final TableItem item = tableBindingsForTriggerSequence
//					.getItem(selection);
//			final Binding binding = (Binding) item.getData(ITEM_DATA_KEY);
//			setContextId(binding.getContextId());
//		}
//
//		update();
//	}
//
//	/**
//	 * Responds to some kind of trigger on the View tab by taking the current
//	 * selection on the key bindings table and selecting the appropriate items
//	 * in the Modify tab.
//	 * 
//	 * @since 3.1
//	 */
//	private final void selectedTableKeyBindings() {
//		final int selectionIndex = tableBindings.getSelectionIndex();
//		if (selectionIndex != -1) {
//			final TableItem item = tableBindings.getItem(selectionIndex);
//			final Binding binding = (Binding) item.getData(BINDING_KEY);
//			editBinding(binding);
//
//		} else {
//			editBinding(null);
//		}
//	}
//
//	/**
//	 * Changes the selected context name in the context combo box. The context
//	 * selected is either the one matching the identifier provided (if
//	 * possible), or the default context identifier. If no matching name can be
//	 * found in the combo, then the first item is selected.
//	 * 
//	 * @param contextId
//	 *            The context identifier for the context to be selected in the
//	 *            combo box; may be <code>null</code>.
//	 */
//	private final void setContextId(final String contextId) {
//		// Clear the current selection.
//		comboContext.clearSelection();
//		comboContext.deselectAll();
//
//		// Figure out which name to look for.
//		String contextName = (String) contextUniqueNamesById.get(contextId);
//		if (contextName == null) {
//			contextName = (String) contextUniqueNamesById
//					.get(IContextIds.CONTEXT_ID_WINDOW);
//		}
//		if (contextName == null) {
//			contextName = Util.ZERO_LENGTH_STRING;
//		}
//
//		// Scan the list for the selection we're looking for.
//		final String[] items = comboContext.getItems();
//		boolean found = false;
//		for (int i = 0; i < items.length; i++) {
//			if (contextName.equals(items[i])) {
//				comboContext.select(i);
//				found = true;
//				break;
//			}
//		}
//
//		// If we didn't find an item, then set the first item as selected.
//		if ((!found) && (items.length > 0)) {
//			comboContext.select(0);
//		}
//	}
//
//	/**
//	 * Sets the current trigger sequence.
//	 * 
//	 * @param keySequence
//	 *            The trigger sequence; may be <code>null</code>.
//	 */
//	private final void setKeySequence(final KeySequence keySequence) {
//		textTriggerSequenceManager.setKeySequence(keySequence);
//	}
//
//	/**
//	 * Changes the selection in the command combo box.
//	 * 
//	 * @param command
//	 *            The fully-parameterized command to select; may be
//	 *            <code>null</code>.
//	 */
//	private final void setParameterizedCommand(
//			final ParameterizedCommand command) {
//		int i = 0;
//		if (commands != null) {
//			final int commandCount = commands.length;
//			for (; i < commandCount; i++) {
//				if (commands[i].equals(command)) {
//					if ((comboCommand.getSelectionIndex() != i)
//							&& (i < comboCommand.getItemCount())) {
//						comboCommand.select(i);
//					}
//					break;
//				}
//			}
//			if ((i >= comboCommand.getItemCount())
//					&& (comboCommand.getSelectionIndex() != 0)) {
//				comboCommand.select(0);
//			}
//		}
//	}
//
//	/**
//	 * Sets the currently selected scheme
//	 * 
//	 * @param scheme
//	 *            The scheme to select; may be <code>null</code>.
//	 */
//	private final void setScheme(final Scheme scheme) {
//		comboScheme.clearSelection();
//		comboScheme.deselectAll();
//		final String schemeUniqueName = (String) schemeUniqueNamesById
//				.get(scheme.getId());
//
//		if (schemeUniqueName != null) {
//			final String items[] = comboScheme.getItems();
//
//			for (int i = 0; i < items.length; i++) {
//				if (schemeUniqueName.equals(items[i])) {
//					comboScheme.select(i);
//					break;
//				}
//			}
//		}
//	}
//
//	/**
//	 * Builds the internal look-up tables before allowing the page to become
//	 * visible.
//	 */
//	public final void setVisible(final boolean visible) {
//		if (visible == true) {
//			Map contextsByName = new HashMap();
//
//			for (Iterator iterator = contextService.getDefinedContextIds()
//					.iterator(); iterator.hasNext();) {
//				Context context = contextService.getContext((String) iterator
//						.next());
//				try {
//					String name = context.getName();
//					Collection contexts = (Collection) contextsByName.get(name);
//
//					if (contexts == null) {
//						contexts = new HashSet();
//						contextsByName.put(name, contexts);
//					}
//
//					contexts.add(context);
//				} catch (final NotDefinedException e) {
//					// Do nothing.
//				}
//			}
//			
//			Map commandsByName = new HashMap();
//
//			for (Iterator iterator = commandService.getDefinedCommandIds()
//					.iterator(); iterator.hasNext();) {
//				Command command = commandService.getCommand((String) iterator
//						.next());
//				if (!isActive(command)) {
//					continue;
//				}
//
//				try {
//					String name = command.getName();
//					Collection commands = (Collection) commandsByName.get(name);
//
//					if (commands == null) {
//						commands = new HashSet();
//						commandsByName.put(name, commands);
//					}
//
//					commands.add(command);
//				} catch (NotDefinedException eNotDefined) {
//					// Do nothing
//				}
//			}
//			
//			// moved here to allow us to remove any empty categories
//			commandIdsByCategoryId = new HashMap();
//
//			for (Iterator iterator = commandService.getDefinedCommandIds()
//					.iterator(); iterator.hasNext();) {
//				final Command command = commandService
//						.getCommand((String) iterator.next());
//				if (!isActive(command)) {
//					continue;
//				}
//
//				try {
//					String categoryId = command.getCategory().getId();
//					Collection commandIds = (Collection) commandIdsByCategoryId
//							.get(categoryId);
//
//					if (commandIds == null) {
//						commandIds = new HashSet();
//						commandIdsByCategoryId.put(categoryId, commandIds);
//					}
//
//					commandIds.add(command.getId());
//				} catch (NotDefinedException eNotDefined) {
//					// Do nothing
//				}
//			}
//
//			Map categoriesByName = new HashMap();
//
//			for (Iterator iterator = commandService.getDefinedCategoryIds()
//					.iterator(); iterator.hasNext();) {
//				Category category = commandService
//						.getCategory((String) iterator.next());
//
//				try {
//					if (commandIdsByCategoryId.containsKey(category.getId())) {
//						String name = category.getName();
//						Collection categories = (Collection) categoriesByName
//								.get(name);
//
//						if (categories == null) {
//							categories = new HashSet();
//							categoriesByName.put(name, categories);
//						}
//
//						categories.add(category);
//					}
//				} catch (NotDefinedException eNotDefined) {
//					// Do nothing
//				}
//			}
//
//			Map schemesByName = new HashMap();
//
//			final Scheme[] definedSchemes = bindingService.getDefinedSchemes();
//			for (int i = 0; i < definedSchemes.length; i++) {
//				final Scheme scheme = definedSchemes[i];
//				try {
//					String name = scheme.getName();
//					Collection schemes = (Collection) schemesByName.get(name);
//
//					if (schemes == null) {
//						schemes = new HashSet();
//						schemesByName.put(name, schemes);
//					}
//
//					schemes.add(scheme);
//				} catch (final NotDefinedException e) {
//					// Do nothing.
//				}
//			}
//
//			contextIdsByUniqueName = new HashMap();
//			contextUniqueNamesById = new HashMap();
//
//			for (Iterator iterator = contextsByName.entrySet().iterator(); iterator
//					.hasNext();) {
//				Map.Entry entry = (Map.Entry) iterator.next();
//				String name = (String) entry.getKey();
//				Set contexts = (Set) entry.getValue();
//				Iterator iterator2 = contexts.iterator();
//
//				if (contexts.size() == 1) {
//					Context context = (Context) iterator2.next();
//					contextIdsByUniqueName.put(name, context.getId());
//					contextUniqueNamesById.put(context.getId(), name);
//				} else {
//					while (iterator2.hasNext()) {
//						Context context = (Context) iterator2.next();
//						String uniqueName = MessageFormat.format(
//								Util.translateString(RESOURCE_BUNDLE,
//										"uniqueName"), new Object[] { name, //$NON-NLS-1$
//										context.getId() });
//						contextIdsByUniqueName.put(uniqueName, context.getId());
//						contextUniqueNamesById.put(context.getId(), uniqueName);
//					}
//				}
//			}
//
//			categoryIdsByUniqueName = new HashMap();
//			categoryUniqueNamesById = new HashMap();
//
//			for (Iterator iterator = categoriesByName.entrySet().iterator(); iterator
//					.hasNext();) {
//				Map.Entry entry = (Map.Entry) iterator.next();
//				String name = (String) entry.getKey();
//				Set categories = (Set) entry.getValue();
//				Iterator iterator2 = categories.iterator();
//
//				if (categories.size() == 1) {
//					Category category = (Category) iterator2.next();
//					categoryIdsByUniqueName.put(name, category.getId());
//					categoryUniqueNamesById.put(category.getId(), name);
//				} else {
//					while (iterator2.hasNext()) {
//						Category category = (Category) iterator2.next();
//						String uniqueName = MessageFormat.format(
//								Util.translateString(RESOURCE_BUNDLE,
//										"uniqueName"), new Object[] { name, //$NON-NLS-1$
//										category.getId() });
//						categoryIdsByUniqueName.put(uniqueName, category
//								.getId());
//						categoryUniqueNamesById.put(category.getId(),
//								uniqueName);
//					}
//				}
//			}
//
//			schemeIdsByUniqueName = new HashMap();
//			schemeUniqueNamesById = new HashMap();
//
//			for (Iterator iterator = schemesByName.entrySet().iterator(); iterator
//					.hasNext();) {
//				Map.Entry entry = (Map.Entry) iterator.next();
//				String name = (String) entry.getKey();
//				Set keyConfigurations = (Set) entry.getValue();
//				Iterator iterator2 = keyConfigurations.iterator();
//
//				if (keyConfigurations.size() == 1) {
//					Scheme scheme = (Scheme) iterator2.next();
//					schemeIdsByUniqueName.put(name, scheme.getId());
//					schemeUniqueNamesById.put(scheme.getId(), name);
//				} else {
//					while (iterator2.hasNext()) {
//						Scheme scheme = (Scheme) iterator2.next();
//						String uniqueName = MessageFormat.format(
//								Util.translateString(RESOURCE_BUNDLE,
//										"uniqueName"), new Object[] { name, //$NON-NLS-1$
//										scheme.getId() });
//						schemeIdsByUniqueName.put(uniqueName, scheme.getId());
//						schemeUniqueNamesById.put(scheme.getId(), uniqueName);
//					}
//				}
//			}
//
//			Scheme activeScheme = bindingService.getActiveScheme();
//
//			// Make an internal copy of the binding manager, for local changes.
//			try {
//				for (int i = 0; i < definedSchemes.length; i++) {
//					final Scheme scheme = definedSchemes[i];
//					final Scheme copy = localChangeManager.getScheme(scheme
//							.getId());
//					copy.define(scheme.getName(), scheme.getDescription(),
//							scheme.getParentId());
//				}
//				localChangeManager.setActiveScheme(bindingService
//						.getActiveScheme());
//			} catch (final NotDefinedException e) {
//				throw new Error(
//						"There is a programmer error in the keys preference page"); //$NON-NLS-1$
//			}
//			localChangeManager.setLocale(bindingService.getLocale());
//			localChangeManager.setPlatform(bindingService.getPlatform());
//			localChangeManager.setBindings(bindingService.getBindings());
//
//			// Populate the category combo box.
//			List categoryNames = new ArrayList(categoryIdsByUniqueName.keySet());
//			Collections.sort(categoryNames, Collator.getInstance());
//			if (commandIdsByCategoryId.containsKey(null)) {
//				categoryNames.add(0, Util.translateString(RESOURCE_BUNDLE,
//						"other")); //$NON-NLS-1$
//			}
//			comboCategory.setItems((String[]) categoryNames
//					.toArray(new String[categoryNames.size()]));
//			comboCategory.clearSelection();
//			comboCategory.deselectAll();
//			if (commandIdsByCategoryId.containsKey(null)
//					|| !categoryNames.isEmpty()) {
//				comboCategory.select(0);
//			}
//
//			// Populate the scheme combo box.
//			List schemeNames = new ArrayList(schemeIdsByUniqueName.keySet());
//			Collections.sort(schemeNames, Collator.getInstance());
//			comboScheme.setItems((String[]) schemeNames
//					.toArray(new String[schemeNames.size()]));
//			setScheme(activeScheme);
//
//			// Update the entire page.
//			update(true);
//		}
//
//		super.setVisible(visible);
//	}
//
//	/**
//	 * Updates the entire preference page -- except the view tab -- based on
//	 * current selection sate. This preference page is written so that
//	 * everything can be made consistent simply by inspecting the state of its
//	 * widgets. A change is triggered by the user, and an event is fired. The
//	 * event triggers an update. It is possible for extra work to be done by
//	 * this page before calling update.
//	 */
//	private final void update() {
//		update(false);
//	}
//
//	/**
//	 * Updates the entire preference page based on current changes. This
//	 * preference page is written so that everything can be made consistent
//	 * simply by inspecting the state of its widgets. A change is triggered by
//	 * the user, and an event is fired. The event triggers an update. It is
//	 * possible for extra work to be done by this page before calling update.
//	 * 
//	 * @param updateViewTab
//	 *            Whether the view tab should be updated as well.
//	 */
//	private final void update(final boolean updateViewTab) {
//		if (updateViewTab) {
//			updateViewTab();
//		}
//		updateComboCommand();
//		updateComboContext();
//		final TriggerSequence triggerSequence = getKeySequence();
//		updateTableBindingsForTriggerSequence(triggerSequence);
//		final ParameterizedCommand command = getParameterizedCommand();
//		updateTableBindingsForCommand(command);
//		final String contextId = getContextId();
//		updateSelection(tableBindingsForTriggerSequence, contextId,
//				triggerSequence);
//		updateSelection(tableBindingsForCommand, contextId, triggerSequence);
//		updateLabelSchemeExtends();
//		updateLabelContextExtends();
//		updateEnabled(triggerSequence, command);
//	}
//
//	/**
//	 * Updates the contents of the commands combo box, based on the current
//	 * selection in the category combo box.
//	 */
//	private final void updateComboCommand() {
//		// Remember the current selection, so we can restore it later.
//		final ParameterizedCommand command = getParameterizedCommand();
//
//		// Figure out where command identifiers apply to the selected category.
//		final String categoryId = getCategoryId();
//		Set commandIds = (Set) commandIdsByCategoryId.get(categoryId);
//		if (commandIds==null) {
//			commandIds = Collections.EMPTY_SET;
//		}
//
//		/*
//		 * Generate an array of parameterized commands based on these
//		 * identifiers. The parameterized commands will be sorted based on their
//		 * names.
//		 */
//		List commands = new ArrayList();
//		final Iterator commandIdItr = commandIds.iterator();
//		while (commandIdItr.hasNext()) {
//			final String currentCommandId = (String) commandIdItr.next();
//			final Command currentCommand = commandService
//					.getCommand(currentCommandId);
//			try {
//				commands.addAll(ParameterizedCommand
//						.generateCombinations(currentCommand));
//			} catch (final NotDefinedException e) {
//				// It is safe to just ignore undefined commands.
//			}
//		}
//		
//		// sort the commands with a collator, so they appear in the
//		// combo correctly
//		commands = sortParameterizedCommands(commands);
//		
//		final int commandCount = commands.size();
//		this.commands = (ParameterizedCommand[]) commands
//				.toArray(new ParameterizedCommand[commandCount]);
//
//		/*
//		 * Generate an array of command names based on this array of
//		 * parameterized commands.
//		 */
//		final String[] commandNames = new String[commandCount];
//		for (int i = 0; i < commandCount; i++) {
//			try {
//				commandNames[i] = this.commands[i].getName();
//			} catch (final NotDefinedException e) {
//				throw new Error(
//						"Concurrent modification of the command's defined state"); //$NON-NLS-1$
//			}
//		}
//
//		/*
//		 * Copy the command names into the combo box, but only if they've
//		 * changed. We do this to try to avoid unnecessary calls out to the
//		 * operating system, as well as to defend against bugs in SWT's event
//		 * mechanism.
//		 */
//		final String[] currentItems = comboCommand.getItems();
//		if (!Arrays.equals(currentItems, commandNames)) {
//			comboCommand.setItems(commandNames);
//		}
//
//		// Try to restore the selection.
//		setParameterizedCommand(command);
//
//		/*
//		 * Just to be extra careful, make sure that we have a selection at this
//		 * point. This line could probably be removed, but it makes the code a
//		 * bit more robust.
//		 */
//		if ((comboCommand.getSelectionIndex() == -1) && (commandCount > 0)) {
//			comboCommand.select(0);
//		}
//	}
//	
//	/**
//	 * Sort the commands using the correct language.
//	 * @param commands the List of ParameterizedCommands
//	 * @return The sorted List
//	 */
//	private List sortParameterizedCommands(List commands) {
//		final Collator collator = Collator.getInstance();
//		
//		// this comparator is based on the ParameterizedCommands#compareTo(*)
//		// method, but uses the collator.
//		Comparator comparator = new Comparator() {
//			public int compare(Object o1, Object o2) {
//				String name1 = null;
//				String name2 = null;
//				try {
//					name1 = ((ParameterizedCommand) o1).getName();
//				} catch (NotDefinedException e) {
//					return -1;
//				}
//				try {
//					name2 = ((ParameterizedCommand) o2).getName();
//				} catch (NotDefinedException e) {
//					return 1;
//				}
//				int rc = collator.compare(name1, name2);
//				if (rc != 0) {
//					return rc;
//				}
//
//				String id1 = ((ParameterizedCommand) o1).getId();
//				String id2 = ((ParameterizedCommand) o2).getId();
//				return collator.compare(id1, id2);
//			}
//		};
//		Collections.sort(commands, comparator);
//		return commands;
//	}
//
//	/**
//	 * Updates the contents of the context combo box, as well as its selection.
//	 */
//	private final void updateComboContext() {
//		final String contextId = getContextId();
//		final Map contextIdsByName = new HashMap(contextIdsByUniqueName);
//
//		final List contextNames = new ArrayList(contextIdsByName.keySet());
//		Collections.sort(contextNames, Collator.getInstance());
//
//		comboContext.setItems((String[]) contextNames
//				.toArray(new String[contextNames.size()]));
//		setContextId(contextId);
//
//		if (comboContext.getSelectionIndex() == -1 && !contextNames.isEmpty()) {
//			comboContext.select(0);
//		}
//	}
//
//	/**
//	 * Updates the enabled state of the various widgets on this page. The
//	 * decision is based on the current trigger sequence and the currently
//	 * selected command.
//	 * 
//	 * @param triggerSequence
//	 *            The current trigger sequence; may be empty, but never
//	 *            <code>null</code>.
//	 * @param command
//	 *            The currently selected command, if any; <code>null</code>
//	 *            otherwise.
//	 */
//	private final void updateEnabled(final TriggerSequence triggerSequence,
//			final ParameterizedCommand command) {
//		final boolean commandSelected = command != null;
//		labelBindingsForCommand.setEnabled(commandSelected);
//		tableBindingsForCommand.setEnabled(commandSelected);
//
//		final boolean triggerSequenceSelected = !triggerSequence.isEmpty();
//		labelBindingsForTriggerSequence.setEnabled(triggerSequenceSelected);
//		tableBindingsForTriggerSequence.setEnabled(triggerSequenceSelected);
//
//		/*
//		 * TODO Do some better button enablement.
//		 */
//		final boolean buttonsEnabled = commandSelected
//				&& triggerSequenceSelected;
//		buttonAdd.setEnabled(buttonsEnabled);
//		buttonRemove.setEnabled(buttonsEnabled);
//		buttonRestore.setEnabled(buttonsEnabled);
//	}
//
//	/**
//	 * Updates the label next to the context that says "extends" if the context
//	 * is a child of another context. If the context is not a child of another
//	 * context, then the label is simply blank.
//	 */
//	private final void updateLabelContextExtends() {
//		final String contextId = getContextId();
//
//		if (contextId != null) {
//			final Context context = contextService.getContext(getContextId());
//			if (context.isDefined()) {
//				try {
//					final String parentId = context.getParentId();
//					if (parentId != null) {
//						final String name = (String) contextUniqueNamesById
//								.get(parentId);
//						if (name != null) {
//							labelContextExtends.setText(MessageFormat.format(
//									Util.translateString(RESOURCE_BUNDLE,
//											"extends"), //$NON-NLS-1$
//									new Object[] { name }));
//							return;
//						}
//					}
//				} catch (final NotDefinedException e) {
//					// Do nothing
//				}
//			}
//		}
//
//		labelContextExtends.setText(Util.ZERO_LENGTH_STRING);
//	}
//
//	/**
//	 * Updates the label next to the scheme that says "extends" if the scheme is
//	 * a child of another scheme. If the scheme is not a child of another
//	 * scheme, then the label is simply blank.
//	 */
//	private final void updateLabelSchemeExtends() {
//		final String schemeId = getSchemeId();
//
//		if (schemeId != null) {
//			final Scheme scheme = bindingService.getScheme(schemeId);
//			try {
//				final String name = (String) schemeUniqueNamesById.get(scheme
//						.getParentId());
//				if (name != null) {
//					labelSchemeExtends.setText(MessageFormat.format(Util
//							.translateString(RESOURCE_BUNDLE, "extends"), //$NON-NLS-1$
//							new Object[] { name }));
//					return;
//				}
//			} catch (final NotDefinedException e) {
//				// Do nothing
//			}
//		}
//
//		labelSchemeExtends.setText(Util.ZERO_LENGTH_STRING);
//	}
//
//	/**
//	 * Tries to select the correct entry in table based on the currently
//	 * selected context and trigger sequence. If the table hasn't really
//	 * changed, then this method is essentially trying to restore the selection.
//	 * If it has changed, then it is trying to select the most entry based on
//	 * the context.
//	 * 
//	 * @param table
//	 *            The table to be changed; must not be <code>null</code>.
//	 * @param contextId
//	 *            The currently selected context; should not be
//	 *            <code>null</code>.
//	 * @param triggerSequence
//	 *            The current trigger sequence; should not be <code>null</code>.
//	 */
//	private final void updateSelection(final Table table,
//			final String contextId, final TriggerSequence triggerSequence) {
//		if (table.getSelectionCount() > 1) {
//			table.deselectAll();
//		}
//
//		final TableItem[] items = table.getItems();
//		int selection = -1;
//		for (int i = 0; i < items.length; i++) {
//			final Binding binding = (Binding) items[i].getData(ITEM_DATA_KEY);
//			if ((Util.equals(contextId, binding.getContextId()))
//					&& (Util.equals(triggerSequence, binding
//							.getTriggerSequence()))) {
//				selection = i;
//				break;
//			}
//		}
//
//		if (selection != -1) {
//			table.select(selection);
//		}
//	}
//
//	/**
//	 * Updates the contents of the table showing the bindings for the currently
//	 * selected command. The selection is destroyed by this process.
//	 * 
//	 * @param parameterizedCommand
//	 *            The currently selected fully-parameterized command; may be
//	 *            <code>null</code>.
//	 */
//	private final void updateTableBindingsForCommand(
//			final ParameterizedCommand parameterizedCommand) {
//		// Clear the table of existing items.
//		tableBindingsForCommand.removeAll();
//
//		// Add each of the bindings, if the command identifier matches.
//		final Collection bindings = localChangeManager
//				.getActiveBindingsDisregardingContextFlat();
//		final Iterator bindingItr = bindings.iterator();
//		while (bindingItr.hasNext()) {
//			final Binding binding = (Binding) bindingItr.next();
//			if (!Util.equals(parameterizedCommand, binding
//					.getParameterizedCommand())) {
//				continue; // binding does not match
//			}
//
//			final TableItem tableItem = new TableItem(tableBindingsForCommand,
//					SWT.NULL);
//			tableItem.setData(ITEM_DATA_KEY, binding);
//
//			/*
//			 * Set the associated image based on the type of binding. Either it
//			 * is a user binding or a system binding.
//			 * 
//			 * TODO Identify more image types.
//			 */
//			if (binding.getType() == Binding.SYSTEM) {
//				tableItem.setImage(0, IMAGE_BLANK);
//			} else {
//				tableItem.setImage(0, IMAGE_CHANGE);
//			}
//
//			String contextName = (String) contextUniqueNamesById.get(binding
//					.getContextId());
//			if (contextName == null) {
//				contextName = Util.ZERO_LENGTH_STRING;
//			}
//			tableItem.setText(1, contextName);
//			tableItem.setText(2, binding.getTriggerSequence().format());
//		}
//	}
//
//	/**
//	 * Updates the contents of the table showing the bindings for the current
//	 * trigger sequence. The selection is destroyed by this process.
//	 * 
//	 * @param triggerSequence
//	 *            The current trigger sequence; may be <code>null</code> or
//	 *            empty.
//	 */
//	private final void updateTableBindingsForTriggerSequence(
//			final TriggerSequence triggerSequence) {
//		// Clear the table of its existing items.
//		tableBindingsForTriggerSequence.removeAll();
//
//		// Get the collection of bindings for the current command.
//		final Map activeBindings = localChangeManager
//				.getActiveBindingsDisregardingContext();
//		final Collection bindings = (Collection) activeBindings
//				.get(triggerSequence);
//		if (bindings == null) {
//			return;
//		}
//
//		// Add each of the bindings.
//		final Iterator bindingItr = bindings.iterator();
//		while (bindingItr.hasNext()) {
//			final Binding binding = (Binding) bindingItr.next();
//			final Context context = contextService.getContext(binding
//					.getContextId());
//			final ParameterizedCommand parameterizedCommand = binding
//					.getParameterizedCommand();
//			final Command command = parameterizedCommand.getCommand();
//			if ((!context.isDefined()) && (!command.isDefined())) {
//				continue;
//			}
//
//			final TableItem tableItem = new TableItem(
//					tableBindingsForTriggerSequence, SWT.NULL);
//			tableItem.setData(ITEM_DATA_KEY, binding);
//
//			/*
//			 * Set the associated image based on the type of binding. Either it
//			 * is a user binding or a system binding.
//			 * 
//			 * TODO Identify more image types.
//			 */
//			if (binding.getType() == Binding.SYSTEM) {
//				tableItem.setImage(0, IMAGE_BLANK);
//			} else {
//				tableItem.setImage(0, IMAGE_CHANGE);
//			}
//
//			try {
//				tableItem.setText(1, context.getName());
//				tableItem.setText(2, parameterizedCommand.getName());
//			} catch (final NotDefinedException e) {
//				throw new Error(
//						"Context or command became undefined on a non-UI thread while the UI thread was processing."); //$NON-NLS-1$
//			}
//		}
//	}
//
//	/**
//	 * Updates the contents of the view tab. This queries the command manager
//	 * for a list of key sequence binding definitions, and these definitions are
//	 * then added to the table.
//	 * 
//	 * @since 3.1
//	 */
//	private final void updateViewTab() {
//		// Clear out the existing table contents.
//		tableBindings.removeAll();
//
//		// Get a sorted list of key binding contents.
//		final List bindings = new ArrayList(localChangeManager
//				.getActiveBindingsDisregardingContextFlat());
//		Collections.sort(bindings, new Comparator() {
//			/**
//			 * Compares two instances of <code>Binding</code> based on the
//			 * current sort order.
//			 * 
//			 * @param object1
//			 *            The first object to compare; must be an instance of
//			 *            <code>Binding</code> (i.e., not <code>null</code>).
//			 * @param object2
//			 *            The second object to compare; must be an instance of
//			 *            <code>Binding</code> (i.e., not <code>null</code>).
//			 * @return The integer value representing the comparison. The
//			 *         comparison is based on the current sort order.
//			 * @since 3.1
//			 */
//			public final int compare(final Object object1, final Object object2) {
//				final Binding binding1 = (Binding) object1;
//				final Binding binding2 = (Binding) object2;
//
//				/*
//				 * Get the category name, command name, formatted key sequence
//				 * and context name for the first binding.
//				 */
//				final Command command1 = binding1.getParameterizedCommand()
//						.getCommand();
//				String categoryName1 = Util.ZERO_LENGTH_STRING;
//				String commandName1 = Util.ZERO_LENGTH_STRING;
//				try {
//					commandName1 = command1.getName();
//					categoryName1 = command1.getCategory().getName();
//				} catch (final NotDefinedException e) {
//					// Just use the zero-length string.
//				}
//				final String triggerSequence1 = binding1.getTriggerSequence()
//						.format();
//				final String contextId1 = binding1.getContextId();
//				String contextName1 = Util.ZERO_LENGTH_STRING;
//				if (contextId1 != null) {
//					final Context context = contextService
//							.getContext(contextId1);
//					try {
//						contextName1 = context.getName();
//					} catch (final org.eclipse.core.commands.common.NotDefinedException e) {
//						// Just use the zero-length string.
//					}
//				}
//
//				/*
//				 * Get the category name, command name, formatted key sequence
//				 * and context name for the first binding.
//				 */
//				final Command command2 = binding2.getParameterizedCommand()
//						.getCommand();
//				String categoryName2 = Util.ZERO_LENGTH_STRING;
//				String commandName2 = Util.ZERO_LENGTH_STRING;
//				try {
//					commandName2 = command2.getName();
//					categoryName2 = command2.getCategory().getName();
//				} catch (final org.eclipse.core.commands.common.NotDefinedException e) {
//					// Just use the zero-length string.
//				}
//				final String keySequence2 = binding2.getTriggerSequence()
//						.format();
//				final String contextId2 = binding2.getContextId();
//				String contextName2 = Util.ZERO_LENGTH_STRING;
//				if (contextId2 != null) {
//					final Context context = contextService
//							.getContext(contextId2);
//					try {
//						contextName2 = context.getName();
//					} catch (final org.eclipse.core.commands.common.NotDefinedException e) {
//						// Just use the zero-length string.
//					}
//				}
//
//				// Compare the items in the current sort order.
//				int compare = 0;
//				for (int i = 0; i < sortOrder.length; i++) {
//					switch (sortOrder[i]) {
//					case VIEW_CATEGORY_COLUMN_INDEX:
//						compare = Util.compare(categoryName1, categoryName2);
//						if (compare != 0) {
//							return compare;
//						}
//						break;
//					case VIEW_COMMAND_COLUMN_INDEX:
//						compare = Util.compare(commandName1, commandName2);
//						if (compare != 0) {
//							return compare;
//						}
//						break;
//					case VIEW_KEY_SEQUENCE_COLUMN_INDEX:
//						compare = Util.compare(triggerSequence1, keySequence2);
//						if (compare != 0) {
//							return compare;
//						}
//						break;
//					case VIEW_CONTEXT_COLUMN_INDEX:
//						compare = Util.compare(contextName1, contextName2);
//						if (compare != 0) {
//							return compare;
//						}
//						break;
//					default:
//						throw new Error(
//								"Programmer error: added another sort column without modifying the comparator."); //$NON-NLS-1$
//					}
//				}
//
//				return compare;
//			}
//
//			/**
//			 * @see Object#equals(java.lang.Object)
//			 */
//			public final boolean equals(final Object object) {
//				return super.equals(object);
//			}
//		});
//
//		// Add a table item for each item in the list.
//		final Iterator keyBindingItr = bindings.iterator();
//		while (keyBindingItr.hasNext()) {
//			final Binding binding = (Binding) keyBindingItr.next();
//
//			// Get the command and category name.
//			final ParameterizedCommand command = binding
//					.getParameterizedCommand();
//			String commandName = Util.ZERO_LENGTH_STRING;
//			String categoryName = Util.ZERO_LENGTH_STRING;
//			try {
//				commandName = command.getName();
//				categoryName = command.getCommand().getCategory().getName();
//			} catch (final org.eclipse.core.commands.common.NotDefinedException e) {
//				// Just use the zero-length string.
//			}
//
//			// Ignore items with a meaningless command name.
//			if ((commandName == null) || (commandName.length() == 0)) {
//				continue;
//			}
//
//			// Get the context name.
//			final String contextId = binding.getContextId();
//			String contextName = Util.ZERO_LENGTH_STRING;
//			if (contextId != null) {
//				final Context context = contextService.getContext(contextId);
//				try {
//					contextName = context.getName();
//				} catch (final org.eclipse.core.commands.common.NotDefinedException e) {
//					// Just use the zero-length string.
//				}
//			}
//
//			// Create the table item.
//			final TableItem item = new TableItem(tableBindings, SWT.NONE);
//			item.setText(VIEW_CATEGORY_COLUMN_INDEX, categoryName);
//			item.setText(VIEW_COMMAND_COLUMN_INDEX, commandName);
//			item.setText(VIEW_KEY_SEQUENCE_COLUMN_INDEX, binding
//					.getTriggerSequence().format());
//			item.setText(VIEW_CONTEXT_COLUMN_INDEX, contextName);
//			item.setData(BINDING_KEY, binding);
//		}
//
//		// Pack the columns.
//		for (int i = 0; i < tableBindings.getColumnCount(); i++) {
//			tableBindings.getColumn(i).pack();
//		}
//	}
//	
//	
//}
